﻿using System;
using System.Collections.Generic;

namespace ttlang
{




    public static class Compiler
    {
        public static bool Debug_DumpLex = false;
        public static bool Debug_DumpSrc = false;
        public static bool Debug_DumpAst = false;
        public static bool Debug_DumpResult = false;
        static Compiler()
        {
            ttlang.semantic.SystemModule.Init();
        }
        public static compiler.CompilerContext CompileExpr(string src)
        {
            var parser = ttlang.src.AntlrTool.GetParserInfo<libttlang_parser.ttlangLexer, libttlang_parser.ttlangParser>("expr");
            var node = parser.ParseAst(src, Debug_DumpSrc, Debug_DumpLex, Debug_DumpAst);
            compiler.CompilerContext ttc = new compiler.CompilerContext();
            CompilerElement.Parse(ttc, "_noname", node);
            //有事就出错了
            ttc.state = compiler.CompileState.SUCC;
            if (Debug_DumpResult)
            {
                Console.WriteLine("=======Result======");
                ttc.resultNode?.Dump(0);
            }
            //这里要加入自己的处理过程
            return ttc;
        }
        public static compiler.CompilerContext CompileCodeBlock(string src)
        {
            var parser = ttlang.src.AntlrTool.GetParserInfo<libttlang_parser.ttlangLexer, libttlang_parser.ttlangParser>("codedoc");
            var node = parser.ParseAst(src, Debug_DumpSrc, Debug_DumpLex, Debug_DumpAst);
            compiler.CompilerContext ttc = new compiler.CompilerContext();
            CompilerElement.Parse(ttc, "_noname", node);
            ttc.state = compiler.CompileState.SUCC;

            if (Debug_DumpResult)
            {
                ttc.resultNode?.Dump(0);
            }
            return ttc;
        }

        /// <summary>
        /// 从路径中编译项目
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static compiler.CompilerContext CompileProject(string path)
        {
            ProjectOption option;
            if (System.IO.File.Exists(path))
            {
                option = ProjectOption.LoadFrom(path);
            }
            else
            {
                var config = System.IO.Path.Combine(path, "ttconfig.json");
                option = ProjectOption.LoadFrom(config);
            }
            var reader = new CodeReader_FromFile(option);
            return CompileProject(option, reader);
        }
        public static compiler.CompilerContext CompileProject(ProjectOption option, ICodeReader reader)
        {
            var parser = ttlang.src.AntlrTool.GetParserInfo<libttlang_parser.ttlangLexer, libttlang_parser.ttlangParser>("doc");

            compiler.CompilerContext ttc = new compiler.CompilerContext();

            ttc.projectOption = option;
            ttc.projectRoot = option.proiectPath;
            //firstpass
            foreach (var file in option.projectfiles)
            {
                var text = reader.GetCode(file);
                if (Compiler.Debug_DumpSrc || Compiler.Debug_DumpLex || Compiler.Debug_DumpAst)
                    Console.WriteLine("@file(" + file + ")");
                var filenode = parser.ParseAst(text, Compiler.Debug_DumpSrc, Compiler.Debug_DumpLex, Compiler.Debug_DumpAst);

                CompilerElement.Parse(ttc, file, filenode);
            }
            //second pass
            CompilerElement.Compile2Pass_NameSpace(ttc, ttc.module._defNameSpace);

            return ttc;
        }

    }
}